/**
 * MIT License
 * 
 * Copyright (c) 2024 - present @ ebraid
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#ifndef __TYPES_H__
#define __TYPES_H__

#ifdef __cplusplus
extern "C" {
#endif

#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
#include <config.h>


#ifndef NULL
typedef ((void*)0)                NULL;
#endif

#ifndef bool
typedef uint8_t                   bool;
#endif

#ifndef false
typedef 0                         false;
#endif

#ifndef true
typedef 1                         true;
#endif

#ifndef uint
typedef unsigned int              uint;
#endif

#ifndef ushort
typedef unsigned short            ushort;
#endif

#ifndef byte
typedef unsigned char             byte;
#endif


#define UNUSED_PTR                0xFFFFFFFE

#define BIT(n)                    (1 << (n))

#define align(x)                  __attribute__((aligned(x)))

#define place_section(sect)       __attribute__((__used__)) __attribute__((section(sect)))

#define spl_section               __attribute__((__used__)) __attribute__((section(".boot_spl")))

#define iomem                     __attribute__((noderef, address_space(2)))

#define weak_func                 __attribute__((weak))


typedef size_t                    virt_addr_t;
typedef size_t                    phys_addr_t;
typedef size_t                    phys_size_t;


/**
 * @brief Get the offset of internal members of the structure
 * 
 * @struct_t: structure typedef 
 * @member: member in structure
 * 
 * @return offset of member in the structure
*/
#define   eb_offsetof(struct_t, member)  ((size_t)&((struct_t*)0)->member)


/**
 * @brief Get the address of the structure instance.
 *
 * @ptr: address of the structure member.
 * @type: type of the structure.
 * @member: member name of the ptr in structure.
 *   
 * @return pointer to address of structure 
 */
#define container_of(ptr, type, member)      ({ \
               (type *)((char *)ptr - eb_offsetof(type, member)); })


#define SZ_16             (0x00000010)
#define SZ_256            (0x00000100)
#define SZ_512            (0x00000200)
#define SZ_1K             (0x00000400)
#define SZ_4K             (0x00001000)
#define SZ_8K             (0x00002000)
#define SZ_16K            (0x00004000)
#define SZ_32K            (0x00008000)
#define SZ_64K            (0x00010000)
#define SZ_128K           (0x00020000)
#define SZ_256K           (0x00040000)
#define SZ_512K           (0x00080000)
#define SZ_1M             (0x00100000)
#define SZ_2M             (0x00200000)
#define SZ_4M             (0x00400000)
#define SZ_8M             (0x00800000)
#define SZ_16M            (0x01000000)
#define SZ_32M            (0x02000000)
#define SZ_64M            (0x04000000)
#define SZ_128M           (0x08000000)
#define SZ_256M           (0x10000000)
#define SZ_512M           (0x20000000)
#define SZ_1G             (0x40000000)
#define SZ_2G             (0x80000000)


#define KHZ               (1000)
#define MHZ               (1000000)
#define GHZ               (1000000000)


/**
 * @brief Get array size
 * 
 * @array: array address
 * 
 * @return size of array 
 */
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
#endif


#define min(a, b)             ((a) < (b) ? (a) : (b))
#define min3(a, b, c)         (min(min(a,b), c))
#define min4(a, b, c, d)      (min(min(a,b), min(c,d)))


#define max(a, b)             ((a) > (b) ? (a) : (b))
#define max3(a, b, c)         (max(max(a,b), c))
#define max4(a, b, c, d)      (max(max(a,b), max(c,d)))


#define _CRT_ABS_DEFINED
#define clamp(min, val, max)  (max(min, (min(val, max))))


#ifdef  abs
#define abs(x)                ((x) > 0 ? (x) : (-(x)))
#endif


#ifdef __cplusplus
}
#endif

#endif //__TYPES_H__
